package com.taiji.workOrder.service.impl;

import java.io.*;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.taiji.common.config.RuoYiConfig;
import com.taiji.common.core.domain.entity.SysDictData;
import com.taiji.common.core.domain.entity.SysDictType;
import com.taiji.common.core.domain.model.LoginUser;
import com.taiji.common.utils.DateUtils;
import com.taiji.common.utils.JwtUtil;
import com.taiji.common.utils.file.FileUploadUtils;
import com.taiji.common.utils.uuid.IdUtils;
import com.taiji.system.service.ISysDictDataService;
import com.taiji.system.service.ISysDictTypeService;
import com.taiji.workOrder.Utils.ChineseTextToPinyin;
import com.taiji.workOrder.Utils.Const;
import com.taiji.workOrder.domain.*;
import com.taiji.workOrder.mapper.*;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import com.taiji.workOrder.Utils.TkService;
import org.springframework.stereotype.Service;
import com.taiji.workOrder.service.IProjectService;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;

/**
 * 项目信息Service业务层处理
 *
 * @author taiji
 * @date 2023-02-26
 */
@Service
public class ProjectServiceImpl implements IProjectService
{
    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private UserProjectMapper userProjectMapper;

    @Autowired
    private TkService tkService;
    @Autowired
    private ISysDictTypeService sysDictTypeService;
    @Autowired
    private WorkOrderMapper workOrderMapper;
    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private OrderEnclosureMapper orderEnclosureMapper;

    private static String defaultBaseDir = RuoYiConfig.getProfile()+"/upload";
    /**
     * 查询项目信息
     *
     * @param id 项目信息主键
     * @return 项目信息
     */
    @Override
    public Project selectProjectById(String id)
    {
        Project project = projectMapper.selectProjectById(id);
        List<UserProject> userProjects = userProjectMapper.selectUserProjectByProjectCode(project.getCode());
        List<Long> collect = userProjects.stream()
                .map(UserProject::getUserId)
                .collect(Collectors.toList());
        project.setUserProjectList(collect);
        return project;
    }

    /**
     * 查询项目信息列表
     *
     * @param project 项目信息
     * @return 项目信息
     */
    @Override
    public List<Project> selectProjectList(Project project)
    {
        return projectMapper.selectProjectList(project);
    }

    /**
     * 新增项目信息
     *
     * @param project 项目信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertProject(Project project) throws Exception {
        project.setId(IdUtils.fastSimpleUUID());
        project.setCreateTime(DateUtils.getNowDate());
//        String code = ChineseTextToPinyin.convertHanzi2Pinyin(project.getName(), false);
        Project projectDistinct = new Project();
        projectDistinct.setName(project.getName());
        projectDistinct.setCode(project.getCode());
        List<Project> projects = projectMapper.selectProjectListDistinct(projectDistinct);
        if (!projects.isEmpty()){
            throw new Exception("项目名称或项目代码重复，请重新输入");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("projectCode",project.getCode());
        String token = JwtUtil.createToken(map);
        project.setToken(token);

        if (project.getUserProjectList()!=null){
            for (int i = 0; i < project.getUserProjectList().size(); i++) {
                UserProject userProject = new UserProject();
                userProject.setUserId(project.getUserProjectList().get(i));
                userProject.setProjectCode(project.getCode());
                userProjectMapper.insertUserProject(userProject);
            }
        }
        SysDictType sysDictType  = new SysDictType();
        sysDictType.setProjectCode(project.getCode());
        sysDictType.setDictName(project.getName()+"编码规则");
        sysDictType.setDictType(project.getCode()+"_bmgz");
        sysDictType.setCreateTime(new Date());
        sysDictType.setCreateBy("system");
        sysDictType.setStatus("1");
        sysDictTypeService.insertDictType(sysDictType);

        SysDictType sysDictType1  = new SysDictType();
        sysDictType1.setProjectCode(project.getCode());
        sysDictType1.setDictName(project.getName()+"工单类型");
        sysDictType1.setDictType(project.getCode()+"_gdlx");
        sysDictType1.setCreateTime(new Date());
        sysDictType1.setCreateBy("system");
        sysDictType1.setStatus("1");
        sysDictTypeService.insertDictType(sysDictType1);
        return projectMapper.insertProject(project);
    }

    /**
     * 修改项目信息
     *
     * @param project 项目信息
     * @return 结果
     */
    @Override
    public int updateProject(Project project)
    {
        project.setUpdateTime(DateUtils.getNowDate());
        //先把原来的项目组成员删了，再新增现在的
        userProjectMapper.deleteUserProjectByProjectCode(project.getCode());
        for (int i = 0; i < project.getUserProjectList().size(); i++) {
            UserProject userProject = new UserProject();
            userProject.setUserId(project.getUserProjectList().get(i));
            userProject.setProjectCode(project.getCode());
            userProjectMapper.insertUserProject(userProject);
        }
        return projectMapper.updateProject(project);
    }

    /**
     * 批量删除项目信息
     *
     * @param ids 需要删除的项目信息主键
     * @return 结果
     */
    @Override
    public int deleteProjectByIds(String[] ids)
    {
        return projectMapper.deleteProjectByIds(ids);
    }

    /**
     * 删除项目信息信息
     *
     * @param id 项目信息主键
     * @return 结果
     */
    @Override
    public int deleteProjectById(String id)
    {
        return projectMapper.deleteProjectById(id);
    }
    /**
     * 查询当前用户的项目列表
     *
     * @param id 项目信息主键
     * @return 结果
     */
    @Override
    public List<Project> getProjectList(String token) throws Exception {
        String substring = token.substring(7);
        if (substring.isEmpty()){
            throw new Exception("未登录");
        }
        LoginUser user = tkService.getLoginUserByToken(substring);
        //如果是管理员，则查看所有的
        if (user.getUser().isAdmin()){
            return projectMapper.selectProjectList(new Project());
        }
        List<UserProject> userProjects = userProjectMapper.selectUserProjectByUserId(user.getUserId());
        List<String> collect = userProjects.stream()
                .map(UserProject::getProjectCode)
                .collect(Collectors.toList());
        if (collect.isEmpty()){
            String uuid = tkService.getUUIDByToken(substring);
            tkService.delLoginUser(uuid);
            throw new Exception("没有分配项目，请联系管理员分配");
        }
        List<Project> projects = projectMapper.selectProjectByIds(collect);
        List<Project> collectForNormalUser = projects.stream()
                .filter(s -> s.getStatus().equals(Const.ProjectStatus.DOING.getKey()))
                .collect(Collectors.toList());
        return collectForNormalUser ;
    }

    @Override
    public void projectExport(String projectCode,HttpServletResponse response) throws IOException {
        /*
        * 1.通过传入的projectCode 拿到 该projectCode 的所有工单附件
        * 2.然后遍历这个工单附件数组，拿到所有item的url
        * 3.通过item.url 用 FileUploadUtils.getAbsoluteFile 拿到该文件的file对象
        * 4.在zip中对应的层级 写入流
        *
        * */
        //查询该项目的所有工单 非创建中
        response.setContentType("application/zip");
        response.setCharacterEncoding("utf-8");
        ZipOutputStream zip = new ZipOutputStream(response.getOutputStream());
        WorkOrder workOrder = new WorkOrder();
        workOrder.setProjectCode(projectCode);
        List<WorkOrder> workOrders = workOrderMapper.selectWorkOrderList(workOrder);
        for (WorkOrder order : workOrders) {
            //根据工单编号 查询工单附件
            OrderEnclosure orderEnclosure = new OrderEnclosure();
            orderEnclosure.setWorkNumber(order.getWorkNumber());
            List<OrderEnclosure> orderEnclosures = orderEnclosureMapper.selectOrderEnclosureList(orderEnclosure);
            for (OrderEnclosure enclosure : orderEnclosures) {
                if ("1".equals(enclosure.getType())){
                    File fileWorker = FileUploadUtils.getAbsoluteFile(defaultBaseDir,enclosure.getUrl().substring(enclosure.getUrl().lastIndexOf("/") + 1));
                    if (!fileWorker.exists()){
                        continue;
                    }
                    ZipEntry zipEntry = new ZipEntry("工单/工单附件/"+enclosure.getName());
                    InputStream  input = new FileInputStream(fileWorker);
                    zip.putNextEntry(zipEntry);
                    IOUtils.copy(input, zip);
                }
                else {
                   File fileReport3= FileUploadUtils.getAbsoluteFile(defaultBaseDir,enclosure.getUrl().substring(enclosure.getUrl().lastIndexOf("/") + 1));
                    if (!fileReport3.exists()){
                        continue;
                    }
                    ZipEntry zipEntry = new ZipEntry("工单/处理过程附件/"+enclosure.getName());
                    InputStream  input = new FileInputStream(fileReport3);
                    zip.putNextEntry(zipEntry);
                    IOUtils.copy(input, zip);
                }
            }
        }
        //查询该项目的所有报告
        Report repo = new Report();
        repo.setProjectCode(projectCode);
        List<Report> reports = reportMapper.selectReportList(repo);
        for (Report report : reports) {
            if ("日报".equals(report.getReportType())){
               File fileReport3 =
                        FileUploadUtils.getAbsoluteFile(defaultBaseDir,report.getUrl().substring(report.getUrl().lastIndexOf("/") + 1));
                if (!fileReport3.exists()){
                    continue;
                }
               ZipEntry zipEntry = new ZipEntry("报告/日报/"+report.getName());
                InputStream  input = new FileInputStream(fileReport3);
                zip.putNextEntry(zipEntry);
                IOUtils.copy(input,zip);
            }
            else if ("月报".equals(report.getReportType())){
                File fileReport3 =
                        FileUploadUtils.getAbsoluteFile(defaultBaseDir,report.getUrl().substring(report.getUrl().lastIndexOf("/") + 1));
                if (!fileReport3.exists()){
                    continue;
                }
                ZipEntry zipEntry = new ZipEntry("报告/月报/"+report.getName());
                InputStream input = new FileInputStream(fileReport3);
                zip.putNextEntry(zipEntry);
                IOUtils.copy(input,zip);
            }
            else if ("季报".equals(report.getReportType())){
               File fileReport3 =
                        FileUploadUtils.getAbsoluteFile(defaultBaseDir,report.getUrl().substring(report.getUrl().lastIndexOf("/") + 1));
                if (!fileReport3.exists()){
                    continue;
                }
                ZipEntry zipEntry = new ZipEntry("报告/季报/"+report.getName());
                InputStream  input = new FileInputStream(fileReport3);
                zip.putNextEntry(zipEntry);
                IOUtils.copy(input, zip);
            }
        }
        zip.finish();
    }


    private static void zipFolder(File folder, String parentFolderName, ZipOutputStream zos) throws IOException {
        for (File file : folder.listFiles()) {
            if (file.isDirectory()) {
                zipFolder(file, parentFolderName + "/" + file.getName(), zos);
            } else {
                byte[] buffer = new byte[1024];
                FileInputStream fis = new FileInputStream(file);
                zos.putNextEntry(new ZipEntry(parentFolderName + "/" + file.getName()));

                int length;
                while ((length = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }

                zos.closeEntry();
                fis.close();
            }
        }
    }

    private static void downloadFile(String fileUrl, String filePath) throws IOException {
        URL url = new URL(fileUrl);
        try (BufferedInputStream in = new BufferedInputStream(url.openStream());
             FileOutputStream fos = new FileOutputStream(filePath)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(buffer, 0, 1024)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        }
    }


    public static void deleteFiles(String folderPath) {
        File folder = new File(folderPath);
        if (folder.exists() && folder.isDirectory()) {
            File[] files = folder.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isFile()) {
                        file.delete();
                    } else if (file.isDirectory()) {
                        deleteFiles(file.getAbsolutePath());
                    }
                }
            }
        }
    }

}
